import { Postcard } from './postcard';
import { navigationWithInterceptor } from "./interceptorService"
import { PretreatmentService } from './pretreatmenService'
import { NavigationCallback } from './navigationCallback'
import router from '@ohos.router';
import { Context } from '@ohos.abilityAccessCtrl';
import { Flags } from './Flags';
import { GlobalContext } from './GlobalContext';
import { NavigationResult } from './navigationResult';


export class HRouter {
  getNavigationResult<T>(params: any): NavigationResult<T> | undefined {
    let navigationResultID = params.navigationResult ?? ''
    let result: NavigationResult<T> | undefined = GlobalContext.getContext().getObject(navigationResultID) as NavigationResult<T>
    GlobalContext.getContext().removeObject(navigationResultID)
    return result
  }

  build(uri: string): Postcard {
    return new Postcard(uri, new Object());
  }

  init(context: Context) {
    globalThis.hRouterModule.resource = context.resourceManager
  }


  public static getInstance(): HRouter {
    if (!globalThis.hRouterModule) {
      globalThis.hRouterModule = {}
    }
    if (!globalThis.hRouterModule.hRouter) {
      let that = new HRouter()
      globalThis.hRouterModule.hRouter = that
    }
    return globalThis.hRouterModule.hRouter
  }

  inject(postcard: Postcard) {
    let rawUri
    try {
      rawUri = globalThis.hRouterModule.resource.getStringByNameSync("hrouter_1_" + postcard.getUri().replace(/\//g, "_1_"))
    } catch (e) {

    }

    if (rawUri) {
      postcard._setRawUri(rawUri)
      postcard.getNavigationCallback()?.onFound(postcard)
    }
  }

  navigation(postcard: Postcard, callback: NavigationCallback) {
    postcard.setNavigationCallback(callback);
    let pretreatmentService: PretreatmentService = postcard.getPretreatmentService() as PretreatmentService;
    if (!pretreatmentService || pretreatmentService.onPretreatment(postcard)) {
      navigationWithInterceptor(postcard)
    }
  }

  _navigation(postcard: Postcard) {
    this.inject(postcard);
    if (!postcard._getRawUri()) {
      postcard.getNavigationCallback()?.onLast(postcard)
      return
    }
    let flags = postcard.getFlags()
    let routerMode = flags & Flags.SINGLE ? router.RouterMode.Single : router.RouterMode.Standard
    if (flags & Flags.REPLACE) {
      router.replaceUrl({
        url: postcard._getRawUri() || '',
        params: postcard.getParams()
      }, routerMode, (error) => {
        if (error) {
          postcard.getNavigationCallback()?.onLast(postcard)
        } else {
          postcard.getNavigationCallback()?.onArrival(postcard)
        }
      })
    } else {
      router.pushUrl({
        url: postcard._getRawUri() || '',
        params: postcard.getParams()
      }, routerMode, (error) => {
        if (error) {
          postcard.getNavigationCallback()?.onLast(postcard)
        } else {
          postcard.getNavigationCallback()?.onArrival(postcard)
        }
      })
    }
  }

  back(postcard: Postcard) {
    let uri = postcard.getUri()
    if (uri) {
      this.inject(postcard);
      router.back({ url: postcard._getRawUri() || '' })
    } else {
      router.back()
    }
  }
}

